package kyu_6;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * Example: names: COLIN,AMANDBA,AMANDAB,CAROL,PauL,JOSEPH weights: [1, 4, 4, 5, 2, 1]

 PAUL -> n = length of firstname + 16 + 1 + 21 + 12 = 4 + 50 -> 54 The weight associated with PAUL is 2 so Paul's winning number is 54 * 2 = 108.

 #Task:

 parameters: st a string of firstnames, we an array of weights, n a rank

 return: the firstname of the participant whose rank is n (ranks are numbered from 1)

 #Example: names: COLIN,AMANDBA,AMANDAB,CAROL,PauL,JOSEPH weights: [1, 4, 4, 5, 2, 1] n: 4

 The function should return: PauL
 */
public class PrizeDraw {

    static class NameScore implements Comparable<NameScore>{
        String name ;
        int score ;

        public NameScore(String name, int score){
            this.name = name ;
            this.score = score ;
        }

        public String getName() {
            return name;
        }

        public int getScore() {
            return score;
        }

        @Override
        public int compareTo(NameScore o) {
            return o.score == this.score ? o.name.compareTo(this.name) : o.score - this.score ;
        }
    }

    private static int nameScore(String name){
        return name.length() + name.toLowerCase().chars().map(x -> x-96).sum() ;
    }

    public static String nthRank2(String st, Integer[] we, int n){
        if(st == null || "".equals(st.trim()))
            return "No participants" ;
        String[] nameArr = st.split(",") ;

        if(n > nameArr.length)
            return "Not enough participants" ;

        List<NameScore> nameScores = IntStream.range(0, nameArr.length).mapToObj(i -> new NameScore(nameArr[i], we[i] * nameScore(nameArr[i])))
                .collect(Collectors.toList());
        //就是comparable与Comparator的区别
        nameScores.sort(Comparator.comparing(NameScore::getScore).reversed().thenComparing(NameScore::getName)) ;
        System.out.println(nameScores.get(0).getName());
        System.out.println(nameScores.get(n-1).getName());



        return IntStream.range(0, nameArr.length).mapToObj(i -> new NameScore(nameArr[i], we[i] * nameScore(nameArr[i])))
                .sorted()
                .collect(Collectors.toList())
                .get(n-1).name ;

    }

    public static String nthRank(String st, Integer[] we, int n) {
        // your code
        if(st == null || "".equals(st.trim()))
            return "No participants" ;
        String[] nameArr = st.split(",") ;

        if(n > nameArr.length)
            return "Not enough participants" ;

        String name = nameArr[n] ;

        if(n > we.length)
            return "Not enough participants" ;

        int len = name.length() ;


        name = name.toLowerCase() ;
        int nameNum = name.chars().map(x ->  x - 96).sum() ;
        nameNum += len ;
        int index = 0 ;

        List<Integer> nums = Arrays.stream(nameArr).map(str->str.toLowerCase()).map(str -> str.concat(lenToStr(str))).map(str -> str.chars().map(c -> c-96).sum()).collect(Collectors.toList()) ;

        Map<Integer, String> map = new HashMap<>() ;

        for(int i=0; i<nums.size();i++){
            nums.set(i, nums.get(i) * we[i]) ;
            map.put(nums.get(i), nameArr[i]) ;
        }
        System.out.println(nums.toString());
        System.out.println(map.toString());
        Comparator<Integer> comparator = (h1, h2) -> h1.compareTo(h2);

        List<Integer> sortNums = nums.stream().sorted(comparator.reversed()).collect(Collectors.toList()); ;
        System.out.println(sortNums.toString());
        int sortNum = sortNums.get(n-1) ;


        return map.get(sortNum) ;

    }

    private static String lenToStr(String str){
        int num = (str.length() + 96) ;
        return new String(Character.toChars(num)) ;
    }

    public static void main(String[] args) {
        String test = nthRank2("COLIN,AMANDBA,AMANDAB,CAROL,PauL,JOSEPH",new Integer[] {1, 4, 4, 5, 2, 1},4) ;
        System.out.println(test);
    }
}
